<script setup lang="ts">
defineOptions({
  name: "baseInfo"
});

import { ref, reactive, onMounted, markRaw, nextTick, inject } from "vue";
import { PxMessage } from "px-ui";
import type { FormInstance, FormRules } from "px-ui";
import { getRelatedFabId, queryRelatedFabQuotaList, queryFabSPECDetail } from "@/api/modules/fab";
import { queryChildByTypeCodeAndItemValue } from "@/api/solidity";
import { checkStartValue } from "./hooks";

const limitData = inject("limitData", ref<Record<string, any>>({}));

interface RuleForm {
  eqpId: string;
  controlLine: Array<string>;
  quotaSingleCode: string;
  indicatorName: string;
  indicatorLevel: string;
  classCode: string;
  systemCode: string;
  point: string;
  pointUnit: string;
  startValue: number;
  step: number;
}

interface ListItem {
  value: string;
  label: string;
  [key: string]: any;
}

const baseInfoRuleForm = defineModel({
  type: Object as PropType<RuleForm>,
  default: () => ({
    eqpId: "",
    controlLine: ["up", "down"],
    quotaSingleCode: "",
    indicatorName: "",
    indicatorLevel: "",
    classCode: "",
    systemCode: "",
    point: "",
    pointUnit: "",
    startValue: undefined,
    step: undefined
  })
});

const pointDisabled = ref<boolean>(true);
const pointUnitDisabled = ref<boolean>(true);
const relatedFabIdOption = ref<Array<ListItem>>([]);
const relatedFabIdLoading = ref(false);
const indicatorNameOption = ref<Array<ListItem>>([]);
const indicatorLevelOption = ref<Array<ListItem>>([]);
const classCodeOption = ref<Array<ListItem>>([]);
const systemCodeOption = ref<Array<ListItem>>([]);
const baseInfoRuleFormRef = ref<FormInstance | null>(null);
const baseInfoRules = reactive<FormRules<RuleForm>>({
  eqpId: [{ required: true, message: "请选择机台ID", trigger: ["blur", "change"] }],
  controlLine: [{ required: false, message: "请至少选择一边", trigger: ["blur", "change"] }],
  quotaSingleCode: [{ required: true, message: "请选择指标名称", trigger: ["blur", "change"] }],
  indicatorLevel: [{ required: true, message: "请选择指标级别", trigger: ["blur", "change"] }],
  classCode: [{ required: true, message: "", trigger: ["blur"] }],
  systemCode: [{ required: true, message: "", trigger: ["blur"] }],
  point: [{ required: true, message: "", trigger: ["blur"] }],
  pointUnit: [{ required: false, message: "", trigger: ["blur", "change"] }],
  startValue: [
    { required: true, message: "请输入Y轴起始值", trigger: ["blur", "change"] },
    {
      validator: (rule: any, value: any, callback: any) => checkStartValue(rule, value, callback, baseInfoRuleForm.value, limitData.value),
      trigger: ["blur", "change"]
    }
  ], //  后端也做了非空校验
  step: [{ required: true, message: "请输入Y轴步进值", trigger: ["blur", "change"] }] //  后端也做了非空校验
});

const emits = defineEmits(["change"]);

const relatedFabIdRemoteMethod = async (fabName: string) => {
  relatedFabIdOption.value = [];
  if (fabName) {
    relatedFabIdLoading.value = true;
    const res = await getRelatedFabId(fabName);
    relatedFabIdOption.value = res.map(item => ({ label: item, value: item }));
    relatedFabIdLoading.value = false;
  }
};

const relatedFabIdChangeHandler = async (val: string) => {
  if (!val) {
    baseInfoRuleForm.value.quotaSingleCode = "";
    baseInfoRuleForm.value.indicatorName = "";
    emits("change", "eqpId", baseInfoRuleForm.value);
    return;
  }
  const t = relatedFabIdOption.value.find(item => item.value === val);
  if (t) {
    const { value: eqpId = "" } = t;
    const res = await queryRelatedFabQuotaList(eqpId);
    if (!res?.length) {
      const msg = `机台（${eqpId}）还未设置关注指标！`;
      PxMessage.error(msg);
      emits("change", "clear", baseInfoRuleForm.value);
      baseInfoRuleForm.value.eqpId = val;
      await nextTick();
      throw new Error(msg);
    }
    indicatorNameOption.value = res.map((item: any) => ({
      ...item,
      value: item.quotaSingleCode,
      label: `${item.materialName || ""}-${item.quotaName || ""}`
    }));
    emits("change", "eqpId", baseInfoRuleForm.value);
  } else {
    const msg = `机台（${val}）还未设置关注指标！`;
    PxMessage.error(msg);
    emits("change", "clear", baseInfoRuleForm.value);
    baseInfoRuleForm.value.eqpId = val;
    await nextTick();
    throw new Error(msg);
  }
};

const clearForm = () => {
  baseInfoRuleForm.value.eqpId = "";
  baseInfoRuleForm.value.controlLine = ["up", "down"];
  baseInfoRuleForm.value.quotaSingleCode = "";
  baseInfoRuleForm.value.indicatorName = "";
  baseInfoRuleForm.value.indicatorLevel = "";
  baseInfoRuleForm.value.classCode = "";
  baseInfoRuleForm.value.systemCode = "";
  baseInfoRuleForm.value.point = "";
  baseInfoRuleForm.value.pointUnit = "";
  baseInfoRuleForm.value.startValue = undefined;
  baseInfoRuleForm.value.step = undefined;
};

const initBaseInfoForm = (data: any, flag?: boolean) => {
  const {
    classCode = "",
    className = "",
    controlLine = [],
    systemCode = "",
    systemName = "",
    point = "",
    pointUnit = "",
    indicatorLevel = "",
    startValue = undefined,
    step = undefined
  } = data;
  // 必显示元素
  classCodeOption.value = [{ value: classCode, label: className }];
  baseInfoRuleForm.value.classCode = classCode;
  systemCodeOption.value = [{ value: systemCode, label: systemName }];
  baseInfoRuleForm.value.systemCode = systemCode;
  baseInfoRuleForm.value.controlLine = controlLine || [];
  baseInfoRuleForm.value.point = point;
  baseInfoRuleForm.value.pointUnit = pointUnit;
  pointDisabled.value = !!point;
  pointUnitDisabled.value = !!pointUnit;
  if (flag) {
    // 编辑显示元素
    baseInfoRuleForm.value.indicatorLevel = indicatorLevel;
    baseInfoRuleForm.value.startValue = Number(startValue);
    baseInfoRuleForm.value.step = Number(step);
  }
};

const indicatorNameChangeHandler = async (val: string) => {
  if (!val) {
    baseInfoRuleForm.value.indicatorName = "";
    emits("change", "clear", baseInfoRuleForm.value);
    return;
  }
  const t = indicatorNameOption.value.find(item => item.value === val);
  baseInfoRuleForm.value.indicatorName = "";
  if (t) {
    baseInfoRuleForm.value.indicatorName = t.label;
    const { spcIndicatorDTO = null } = t;
    if (!spcIndicatorDTO) {
      t["controlLine"] = ["up", "down"];
      initBaseInfoForm(t);
      emits("change", "quotaSingleCode", baseInfoRuleForm.value, t);
      return;
    }
    const { quotaSingleCode = "" } = spcIndicatorDTO;
    const res = await queryFabSPECDetail({ quotaSingleCode });
    if (!res) {
      initBaseInfoForm(t);
      emits("change", "quotaSingleCode", baseInfoRuleForm.value, t);
      return;
    }
    initBaseInfoForm(res, true);
    emits("change", "quotaSingleCode", baseInfoRuleForm.value, res);
  }
};

const queryIndicatorLevelOptionFn = async () => {
  const res: Array<any> = await queryChildByTypeCodeAndItemValue({ typeCode: "SPCL" });
  indicatorLevelOption.value = res.map(item => ({ ...item, label: item.itemName, value: item.itemValue }));
};

const validate = (): Promise<Record<string, any>> => {
  return new Promise((resolve, reject) => {
    if (!baseInfoRuleFormRef.value) return reject(false);
    baseInfoRuleFormRef.value.validate(valid => {
      if (valid) {
        resolve(markRaw(baseInfoRuleForm.value));
      } else {
        reject(false);
      }
    });
  });
};

const reset = () => {
  if (!baseInfoRuleFormRef.value) return;
  baseInfoRuleFormRef.value.resetFields();
};

const init = async (data: any, flag: boolean = false) => {
  baseInfoRuleFormRef.value.resetFields();
  const { eqpId = "", quotaSingleCode = "", indicatorName = "" } = data;
  await relatedFabIdRemoteMethod(eqpId);
  baseInfoRuleForm.value.eqpId = eqpId;
  await relatedFabIdChangeHandler(eqpId);
  if (indicatorNameOption.value.some(item => item.value === quotaSingleCode)) {
    baseInfoRuleForm.value.quotaSingleCode = quotaSingleCode;
    await indicatorNameChangeHandler(quotaSingleCode);
    flag && initBaseInfoForm(data, true);
  } else {
    PxMessage.warning(`注意：机台（${eqpId}）下的指标（${indicatorName}）已被取消关注！！`);
    emits("change", "clear", baseInfoRuleForm.value);
    baseInfoRuleForm.value.eqpId = eqpId;
  }
};

onMounted(async () => {
  await queryIndicatorLevelOptionFn();
});

defineExpose({
  baseInfoRuleFormRef,
  baseInfoRuleForm,
  clearForm,
  validate,
  reset,
  init
});
</script>

<template>
  <px-form
    ref="baseInfoRuleFormRef"
    :model="baseInfoRuleForm"
    :rules="baseInfoRules"
    label-width="120px"
    class="base-info-form"
    scroll-to-error
    status-icon
  >
    <px-row :gutter="24">
      <px-col :span="8">
        <px-form-item label="机台ID" prop="eqpId">
          <px-select
            v-model="baseInfoRuleForm.eqpId"
            clearable
            filterable
            remote
            reserve-keyword
            remote-show-suffix
            no-data-text="该机台不存在或未与系统关联！"
            placeholder="请选择机台ID"
            :remote-method="relatedFabIdRemoteMethod"
            :loading="relatedFabIdLoading"
            @change="relatedFabIdChangeHandler"
          >
            <px-option v-for="item in relatedFabIdOption" :key="item.value" :label="item.label" :value="item.value" />
          </px-select>
        </px-form-item>
      </px-col>

      <px-col :span="16">
        <px-form-item label="双/单边控制限" prop="controlLine">
          <px-checkbox-group v-model="baseInfoRuleForm.controlLine">
            <px-checkbox label="up">上单边</px-checkbox>
            <px-checkbox label="down">下单边</px-checkbox>
          </px-checkbox-group>
        </px-form-item>
      </px-col>

      <px-col :span="8">
        <px-form-item label="指标名称" prop="quotaSingleCode">
          <px-select
            v-model="baseInfoRuleForm.quotaSingleCode"
            clearable
            filterable
            placeholder="请选择指标名称"
            @change="indicatorNameChangeHandler"
          >
            <px-option v-for="item in indicatorNameOption" :key="item.value" :label="item.label" :value="item.value" />
          </px-select>
        </px-form-item>
      </px-col>

      <px-col :span="8">
        <px-form-item label="指标级别" prop="indicatorLevel">
          <px-select v-model="baseInfoRuleForm.indicatorLevel" clearable filterable placeholder="请选择指标级别">
            <px-option v-for="item in indicatorLevelOption" :key="item.value" :label="item.label" :value="item.value" />
          </px-select>
        </px-form-item>
      </px-col>

      <px-col :span="8">
        <px-form-item label="科室" prop="classCode">
          <px-select v-model="baseInfoRuleForm.classCode" disabled clearable filterable>
            <px-option v-for="item in classCodeOption" :key="item.value" :label="item.label" :value="item.value" />
          </px-select>
        </px-form-item>
      </px-col>

      <px-col :span="8">
        <px-form-item label="系统" prop="systemCode">
          <px-select v-model="baseInfoRuleForm.systemCode" disabled clearable filterable>
            <px-option v-for="item in systemCodeOption" :key="item.value" :label="item.label" :value="item.value" />
          </px-select>
        </px-form-item>
      </px-col>

      <px-col :span="8">
        <px-form-item label="点位" prop="point">
          <px-input v-model.trim="baseInfoRuleForm.point" :disabled="pointDisabled" clearable placeholder="" />
        </px-form-item>
      </px-col>

      <px-col :span="8">
        <px-form-item label="点位单位" prop="pointUnit">
          <px-input v-model.trim="baseInfoRuleForm.pointUnit" :disabled="pointUnitDisabled" clearable placeholder="" />
        </px-form-item>
      </px-col>

      <px-col :span="8">
        <px-form-item label="Y轴起始值" prop="startValue">
          <px-input
            v-model.trim.number="baseInfoRuleForm.startValue"
            class="px-input-number-no-controls"
            type="number"
            clearable
            placeholder="请输入Y轴起始值"
          />
        </px-form-item>
      </px-col>

      <px-col :span="8">
        <px-form-item label="Y轴步进值" prop="step">
          <px-input
            v-model.trim.number="baseInfoRuleForm.step"
            class="px-input-number-no-controls"
            type="number"
            clearable
            :min="0"
            placeholder="请输入Y轴步进值"
          />
        </px-form-item>
      </px-col>
    </px-row>
  </px-form>
</template>

<style lang="scss" scoped>
.base-info-form {
  box-sizing: border-box;
  padding: 16px;
  padding-bottom: 0;
}

:deep(.px-form-item) {
  .px-input-number .px-input__inner {
    text-align: left;
  }

  .px-select,
  .px-input-number {
    width: 100%;
  }
}
</style>
